package game.Russian;

import java.awt.BorderLayout;
import java.awt.Dimension;
import java.math.BigInteger;

import javax.swing.BorderFactory;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JSlider;
import javax.swing.JTextField;
import javax.swing.SwingUtilities;
import javax.swing.event.DocumentEvent;
import javax.swing.event.DocumentListener;
import javax.swing.text.BadLocationException;
import javax.swing.text.Document;

public class Convert extends JFrame {

	private static final long serialVersionUID = 1L;
	private int inHex=10;
	private int outHex=10;
	private JLabel binary =new JLabel();//2进制
	private JLabel oct =new JLabel();//8进制
	private JLabel dec= new JLabel();//10进制
	private JLabel hex=new JLabel();//16进制
	private JLabel define=new JLabel();//自定义进制

	private String regex="[0-9]+";

	public Convert() {
		super.setTitle("进制转化器");
		this.setBounds(300,300,800,350);
		this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		initTopGUI();//界面布局(顶部)
		initCenterGUI();//界面布局(中部)
		this.setVisible(true);
		this.setResizable(false);
	}
	//中部组件的创建、位置属性设置。
	public void initCenterGUI() {
		JPanel center=new JPanel(null);
		center.setBorder(BorderFactory.createTitledBorder("各进制转化结果："));
		JLabel binaryTitle=new JLabel("二进制:");
		JLabel octTitle=new JLabel("八进制:");
		JLabel decTitle=new JLabel("十进制:");
		JLabel hexTitle=new JLabel("十六进制:");
		JLabel defineTitle=new JLabel("自定义:");
		binaryTitle.setBounds(10,20,70,30);
		binary.setBounds(90, 20, 650, 30);
		octTitle.setBounds(10,60,70,30);
		oct.setBounds(90, 60, 650, 30);
		decTitle.setBounds(10,100,70,30);
		dec.setBounds(90, 100, 650, 30);
		hexTitle.setBounds(10,140,70,30);
		hex.setBounds(90, 140, 650, 30);
		defineTitle.setBounds(10,180,70,30);
		define.setBounds(90, 180, 650, 30);
		center.add(binary);
		center.add(oct);
		center.add(dec);
		center.add(define);
		center.add(hex);
		center.add(binaryTitle);
		center.add(octTitle);
		center.add(decTitle);
		center.add(hexTitle);
		center.add(defineTitle);
		this.add(center);
	}
	//界面布局(顶部)
	public void initTopGUI() {
		//给顶部组件，添加个顶部面板，并使用标题边框修饰。
		JPanel top=new JPanel(null);
		top.setBorder(BorderFactory.createTitledBorder("输入转化数值"));
		top.setPreferredSize(new Dimension(800, 100));
		//输入框创建和各属性设置。
		JTextField input=new JTextField("");
		input.setHorizontalAlignment(JTextField.LEFT);
		input.setBounds(10, 35, 400, 30);
		top.add(input);	//添加至顶部面板

		//输入（出）进制滑杆创建和各属性设置。
		JSlider in=new JSlider(2,36,10);
		JLabel inLab=new JLabel("输入进制:"+inHex);
		JSlider out=new JSlider(2,36,10);
		JLabel outLab=new JLabel("输出进制:"+outHex);
		in.setMinorTickSpacing(1);
		out.setMinorTickSpacing(1);
		in.setPaintTicks(true);
		out.setPaintTicks(true);
		in.setSnapToTicks(true);
		out.setSnapToTicks(true);
		in.setBounds(510,15,270,30);
		out.setBounds(510,55,270,30);
		inLab.setBounds(430,15,70,30);
		outLab.setBounds(430,55,70,30);
		//添加至顶部面板
		top.add(in);
		top.add(inLab);
		top.add(out);
		top.add(outLab);
		//添加至顶部面板
		this.add(top,BorderLayout.NORTH);
		//给输入框绑定一个属性事件
		boundInputEvent(input);
		in.addChangeListener(e->{
			JSlider js=(JSlider)e.getSource();
			inLab.setText(inLab.getText().replaceAll("\\d+","")+js.getValue());
			input.setText("");
			this.inHex=js.getValue();
			//
			if(inHex<=10) {
				regex="-?[0-"+(inHex-1)+"]++";
			}else {
				char end=(char)('a'+(inHex-11));
				regex="-?[0-9a-"+end+"]++";
			}
		});
		out.addChangeListener(e->{
			JSlider js=(JSlider)e.getSource();
			outLab.setText(outLab.getText().replaceAll("\\d+","")+js.getValue());
			this.outHex=js.getValue();
			computeHEX(input.getText());
		});
	}

	//输入框绑定属性事件和事件处理。
	public void boundInputEvent(JTextField text) {
		Document doc=text.getDocument();
		//监听输入框的内容
		doc.addDocumentListener(new DocumentListener() {

			public void insertUpdate(DocumentEvent e) {
				String value=text.getText();
				//如果文本内容不符合正则验证，删除新增内容。在EDT线程中进行
				if(!value.matches(regex)) {
					SwingUtilities.invokeLater(()->{
						try {
							doc.remove(e.getOffset(), e.getLength());
						} catch (BadLocationException e1) {
							e1.printStackTrace();
						}
					});
				}
				//将文本框内容左进制转换，在EDT线程中进行。
				SwingUtilities.invokeLater(()->{
					try {
						//进制转化
						computeHEX(doc.getText(0,doc.getLength()));
					} catch (BadLocationException e1) {
						e1.printStackTrace();
					}
				});
			}
			public void removeUpdate(DocumentEvent e) {}
			public void changedUpdate(DocumentEvent e) {}
		});
	}
	//将Value转化成其它进制
	public void computeHEX(String value) {
		if(value==null || value.equals("")) return;
		//根据输入进制inHex创建BigInteger
		BigInteger bigint=new BigInteger(value, inHex);

		dec.setText(bigint.toString(10));
		//如果是二进制，将二进制每4位用空格空开(从右到左)
		String brv=new StringBuilder(bigint.toString(2)).reverse().toString();
		brv=brv.replaceAll("(.{4})", "$1 ");
		binary.setText(new StringBuilder(brv).reverse().toString());
		oct.setText(bigint.toString(8));
		hex.setText(bigint.toString(16));
		//根据输出进制outHex,转化成目标进制格式
		define.setText(bigint.toString(outHex));
	}

	public static void main(String[] args) {
		SwingUtilities.invokeLater(()->new Convert());
	}
}
